home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************************/
- /* FILE.C - File and view related functions. */
- /***********************************************************************/
- /*
- * THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
- * Copyright (C) 1991-1995 Mark Hessling
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to:
- *
- * The Free Software Foundation, Inc.
- * 675 Mass Ave,
- * Cambridge, MA 02139 USA.
- *
- *
- * If you make modifications to this software that you feel increases
- * it usefulness for the rest of the community, please email the
- * changes, enhancements, bug fixes as well as any and all ideas to me.
- * This software is going to be maintained and enhanced as deemed
- * necessary by the community.
- *
- * Mark Hessling email: M.Hessling@gu.edu.au
- * 36 David Road Phone: +61 7 849 7731
- * Holland Park Fax: +61 7 875 5314
- * QLD 4121
- * Australia
- */
-
- /*
- $Id: file.c 2.0 1995/01/26 16:31:04 MH Release MH $
- */
-
- #include <stdio.h>
- #include <errno.h>
-
- #include "the.h"
- #include "directry.h"
- #include "proto.h"
-
- #if defined(DOS) || defined(OS2)
- #include <io.h>
- #endif
-
- /****************** needs to be fixed *************/
- #ifdef GO32
- #define stricmp strcasecmp
- #endif
-
- /*#define TRACE*/
- /***********************************************************************/
- #ifdef PROTO
- short get_file(CHARTYPE *filename)
- #else
- short get_file(filename)
- CHARTYPE *filename;
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- extern struct stat stat_buf;
- extern bool in_profile;
- extern CHARTYPE file_disposition;
- extern CHARTYPE *rexxoutname;
- extern CHARTYPE number_of_files;
- extern CHARTYPE rexx_filename[10];
- extern CHARTYPE rexx_pathname[MAX_FILE_NAME+1];
- extern CHARTYPE dir_filename[10];
- extern CHARTYPE dir_pathname[MAX_FILE_NAME+1];
- extern CHARTYPE sp_path[MAX_FILE_NAME+1];
- extern CHARTYPE sp_fname[MAX_FILE_NAME+1];
- /*--------------------------- local data ------------------------------*/
- LINE *curr=NULL;
- CHARTYPE work_filename[MAX_FILE_NAME+1] ;
- VIEW_DETAILS *save_current_view=NULL,*found_file=NULL;
- short rc=RC_OK;
- bool directory_file=FALSE;
- FILE_DETAILS *save_current_file=NULL;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("file.c: get_file");
- #endif
- /*---------------------------------------------------------------------*/
- /* Split the filename supplied into directory and filename parts. */
- /* This is done before allocating a new current_file number. */
- /*---------------------------------------------------------------------*/
-
- if ((rc = splitpath(filename)) != RC_OK)
- {
- display_error(10,filename,FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
- /*---------------------------------------------------------------------*/
- /* If the filename portion of the splithpath is empty, then we are */
- /* editing a directory. So create the new file with the appropriate OS*/
- /* command and set the filename to DIR.DIR. */
- /*---------------------------------------------------------------------*/
- if (strcmp(sp_fname,"") == 0)
- {
- if ((rc = read_directory()) != RC_OK)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
- strcpy(sp_path,dir_pathname);
- strcpy(sp_fname,dir_filename);
- }
- /*---------------------------------------------------------------------*/
- /* If this is the first file to be edited, don't check to see if the */
- /* file is already in the ring. Obvious hey! */
- /*---------------------------------------------------------------------*/
- if (CURRENT_VIEW == (VIEW_DETAILS *)NULL) /* no files in ring yet */
- {
- if ((rc = defaults_for_first_file()) != RC_OK)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
- }
- else
- {
- /*---------------------------------------------------------------------*/
- /* Here we should check if we already have the file to be edited in */
- /* the ring. If the file is there and it is DIR.DIR, QQUIT out of it */
- /* otherwise set the current pointer to it and exit. */
- /* Same applies to REXX output file. */
- /*---------------------------------------------------------------------*/
- save_current_view = CURRENT_VIEW;
- if ((found_file = find_file(sp_path,sp_fname)) != (VIEW_DETAILS *)NULL)
- {
- CURRENT_VIEW = found_file;
- /* if (CURRENT_FILE->pseudo_file == PSEUDO_DIR
- || CURRENT_FILE->pseudo_file == PSEUDO_REXX)*/
- if ((strcmp(CURRENT_FILE->fname,dir_filename) == 0
- && strcmp(CURRENT_FILE->fpath,dir_pathname) == 0)
- || (strcmp(CURRENT_FILE->fname,rexx_filename) == 0
- && strcmp(CURRENT_FILE->fpath,rexx_pathname) == 0))
- {
- Qquit("");
- if (CURRENT_VIEW == (VIEW_DETAILS *)NULL)
- rc = defaults_for_first_file();
- else
- {
- save_current_file = CURRENT_FILE;
- rc = defaults_for_other_files(FALSE);
- }
- if (rc != RC_OK)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
- }
- else
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OK);
- }
- }
- else
- {
- CURRENT_VIEW = save_current_view;
- save_current_file = CURRENT_FILE;
- if ((rc = defaults_for_other_files(FALSE)) != RC_OK)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
- }
- }
- /*---------------------------------------------------------------------*/
- /* Increment the number of files in storage here, so that if there are */
- /* any problems with reading the file, free_file_memory() function can */
- /* correctly decrement the number of files. */
- /*---------------------------------------------------------------------*/
- number_of_files++;
- /*---------------------------------------------------------------------*/
- /* Allocate memory to file pointer. */
- /*---------------------------------------------------------------------*/
- if ((CURRENT_FILE = (FILE_DETAILS *)(*the_malloc)(sizeof(FILE_DETAILS))) == NULL)
- {
- free_view_memory();
- display_error(30,(CHARTYPE *)"",FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OUT_OF_MEMORY);
- }
- /*---------------------------------------------------------------------*/
- /* Allocate space for file's colour attributes... */
- /*---------------------------------------------------------------------*/
- if ((CURRENT_FILE->attr = (COLOUR_ATTR *)(*the_malloc)(ATTR_MAX*sizeof(COLOUR_ATTR))) == NULL)
- {
- display_error(30,(CHARTYPE *)"",FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OUT_OF_MEMORY);
- }
- memset(CURRENT_FILE->attr,0,ATTR_MAX*sizeof(COLOUR_ATTR));
- /*---------------------------------------------------------------------*/
- /* Set up default file attributes. */
- /*---------------------------------------------------------------------*/
- default_file_attributes(save_current_file);
- if (strcmp(dir_filename,sp_fname) == 0)
- CURRENT_FILE->pseudo_file = PSEUDO_DIR;
- if (strcmp(rexxoutname,sp_fname) == 0)
- CURRENT_FILE->pseudo_file = PSEUDO_REXX;
- /*---------------------------------------------------------------------*/
- /* Copy the filename and path strings split up at the start of the */
- /* function. */
- /*---------------------------------------------------------------------*/
- if ((CURRENT_FILE->fname = (CHARTYPE *)(*the_malloc)(strlen(sp_fname)+1)) == NULL)
- {
- free_view_memory();
- display_error(30,(CHARTYPE *)"",FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OUT_OF_MEMORY);
- }
- if ((CURRENT_FILE->fpath = (CHARTYPE *)(*the_malloc)(strlen(sp_path)+1)) == NULL)
- {
- free_view_memory();
- display_error(30,(CHARTYPE *)"",FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OUT_OF_MEMORY);
- }
- strcpy(CURRENT_FILE->fname,sp_fname);
- strcpy(CURRENT_FILE->fpath,sp_path);
-
- strcpy(work_filename,sp_path);
- strcat(work_filename,sp_fname);
- /*---------------------------------------------------------------------*/
- /* If the file is not readable, then display error. */
- /*---------------------------------------------------------------------*/
- if (!file_readable(work_filename))
- {
- display_error(8,work_filename,FALSE);
- free_view_memory();
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_ACCESS_DENIED);
- }
-
- if (file_exists(work_filename))
- {
- if (file_writable(work_filename))
- file_disposition = FILE_NORMAL;
- else
- {
- file_disposition = FILE_READONLY;
- if (!in_profile)
- display_error(0,(CHARTYPE *)"File is read-only...",FALSE);
- }
- if ((CURRENT_FILE->fp = fopen(work_filename,"r")) == NULL)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_ACCESS_DENIED);
- }
- }
- else
- {
- file_disposition = FILE_NEW;
- if (!in_profile)
- display_error(0,(CHARTYPE *)"New file...",TRUE);
- }
- /*---------------------------------------------------------------------*/
- /* first_line is set to "Top of File" */
- /*---------------------------------------------------------------------*/
- if ((CURRENT_FILE->first_line = add_line(CURRENT_FILE->first_line,NULL,TOP_OF_FILE,
- strlen(TOP_OF_FILE),0)) == NULL)
- {
- free_view_memory();
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OUT_OF_MEMORY);
- }
-
- curr = CURRENT_FILE->first_line;
- /*---------------------------------------------------------------------*/
- /* Read in the existing file... */
- /*---------------------------------------------------------------------*/
- CURRENT_FILE->number_lines = 0L;
- if (file_disposition != FILE_NEW)
- {
- stat(work_filename,&stat_buf);
- CURRENT_FILE->fmode = stat_buf.st_mode;
- if ((curr = read_file(CURRENT_FILE->fp,curr,work_filename)) == NULL)
- {
- free_view_memory();
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_ACCESS_DENIED);
- }
- }
- else
- CURRENT_FILE->fmode = FMODE;
- /*---------------------------------------------------------------------*/
- /* last line is set to "Bottom of File" */
- /*---------------------------------------------------------------------*/
- if ((CURRENT_FILE->last_line = add_line(CURRENT_FILE->first_line,curr,BOTTOM_OF_FILE,
- strlen(BOTTOM_OF_FILE),0)) == NULL)
- {
- free_view_memory();
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OUT_OF_MEMORY);
- }
-
- if (file_disposition != FILE_NEW)
- fclose(CURRENT_FILE->fp);
-
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OK);
- }
- #ifndef MSWIN
- /***********************************************************************/
- #ifdef PROTO
- LINE *read_file(FILE *fp,LINE *curr,CHARTYPE *filename)
- #else
- LINE *read_file(fp,curr,filename)
- FILE *fp;
- LINE *curr;
- CHARTYPE *filename;
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- extern CHARTYPE TABI_ONx;
- extern CHARTYPE TABI_Nx;
- extern CHARTYPE *rec;
- /*--------------------------- local data ------------------------------*/
- register unsigned short i=0;
- short ch=0;
- LINE *temp=NULL;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("file.c: read_file");
- #endif
- temp = curr;
- memset(rec,' ',max_line_length);
- i = 0;
- while(1)
- {
- ch = fgetc(fp);
- if (feof(fp))
- {
- if (i > 0) /* line with no CR and/or CR/LF */
- {
- if ((temp = add_line(CURRENT_FILE->first_line,temp,rec,i,0)) == NULL)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(NULL);
- }
- CURRENT_FILE->number_lines++;
- }
- break;
- }
- if (ch == '\t'&& TABI_ONx)
- {
- do
- {
- rec[i] = ' ';
- i++;
- if (i >= max_line_length)
- {
- sprintf(rec,"Line %d exceeds max. width of %d",CURRENT_FILE->number_lines+1,max_line_length);
- display_error(29,rec,FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(NULL);
- }
- }
- while ((i % TABI_Nx) != 0);
- continue;
- }
- if (ch == '\n')
- {
- rec[i] = '\0';
- if ((temp = add_line(CURRENT_FILE->first_line,temp,rec,i,0)) == NULL)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(NULL);
- }
- CURRENT_FILE->number_lines++;
- i = 0;
- memset(rec,' ',max_line_length);
- continue;
- }
- if (ch == '\r')
- {
- rec[i] = ch;
- i++;
- ch = fgetc(fp);
- if (feof(fp))
- break;
- if (ch == '\n')
- {
- --i;
- rec[i] = '\0';
- if ((temp = add_line(CURRENT_FILE->first_line,temp,rec,i,0)) == NULL)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(NULL);
- }
- CURRENT_FILE->number_lines++;
- i = 0;
- memset(rec,' ',max_line_length);
- continue;
- }
- }
- rec[i] = ch;
- i++;
- if (i >= max_line_length)
- {
- sprintf(rec,"Line %d exceeds max. width of %d",CURRENT_FILE->number_lines+1,max_line_length);
- display_error(29,rec,FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(NULL);
- }
- }
- #ifdef TRACE
- trace_return();
- #endif
- return(temp);
- }
- #endif
- /***********************************************************************/
- #ifdef PROTO
- short save_file(FILE_DETAILS *cf,CHARTYPE *new_fname,bool force,LINETYPE in_lines,
- LINETYPE start_line,bool append,short start_col, short end_col,bool ignore_scope)
- #else
- short save_file(cf,new_fname,force,in_lines,start_line,append,start_col,end_col,ignore_scope)
- FILE_DETAILS *cf;
- CHARTYPE *new_fname;
- bool force,append;
- LINETYPE in_lines,start_line;
- short start_col,end_col;
- bool ignore_scope;
- #endif
- /***********************************************************************/
- {
- /*------------------------- external data -----------------------------*/
- extern CHARTYPE sp_fname[MAX_FILE_NAME+1];
- extern CHARTYPE sp_path[MAX_FILE_NAME+1];
- /*--------------------------- local data ------------------------------*/
- CHARTYPE *bak_filename=NULL;
- CHARTYPE *write_fname=NULL;
- register short i=0;
- LINETYPE j=0L;
- LINETYPE num_lines=in_lines;
- LINE *curr=NULL;
- FILE *fp=NULL;
- unsigned short col=0,newcol=0;
- short off=0;
- CHARTYPE c=0;
- short rc=RC_OK;
- bool same_file=TRUE;
- short anerror=0;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("file.c: save_file");
- #endif
- if ((write_fname = (CHARTYPE *)(*the_malloc)(MAX_FILE_NAME)) == NULL)
- {
- display_error(30,(CHARTYPE *)"",FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OUT_OF_MEMORY);
- }
- /*---------------------------------------------------------------------*/
- /* If a new filename is specified, use it as the old filename. */
- /*---------------------------------------------------------------------*/
- (void *)strtrans(new_fname,OSLASH,ISLASH);
- if (strcmp(new_fname,"") != 0) /* new_fname supplied */
- {
- /*---------------------------------------------------------------------*/
- /* Split the supplied new filename. */
- /*---------------------------------------------------------------------*/
- if ((rc = splitpath(new_fname)) != RC_OK)
- {
- display_error(10,new_fname,FALSE);
- if (bak_filename != (CHARTYPE *)NULL)
- (*the_free)(bak_filename);
- if (write_fname != (CHARTYPE *)NULL)
- (*the_free)(write_fname);
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
- strcpy(write_fname,sp_path);
- strcat(write_fname,sp_fname);
- same_file = FALSE;
- /*---------------------------------------------------------------------*/
- /* Test to make sure that the write fname doesn't exist... */
- /* ...unless we are forcing the write. */
- /*---------------------------------------------------------------------*/
- if ((!force) && file_exists(write_fname))
- {
- display_error(31,write_fname,FALSE);
- if (bak_filename != (CHARTYPE *)NULL)
- (*the_free)(bak_filename);
- if (write_fname != (CHARTYPE *)NULL)
- (*the_free)(write_fname);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_ACCESS_DENIED);
- }
- /*---------------------------------------------------------------------*/
- /* Test to make sure that we can write the file. */
- /*---------------------------------------------------------------------*/
- if (!file_writable(write_fname))
- {
- display_error(8,write_fname,FALSE);
- if (bak_filename != (CHARTYPE *)NULL)
- (*the_free)(bak_filename);
- if (write_fname != (CHARTYPE *)NULL)
- (*the_free)(write_fname);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_ACCESS_DENIED);
- }
- }
- else
- {
- /*---------------------------------------------------------------------*/
- /* We are using the same file name for the new file. */
- /* Create the name of the current file. */
- /*---------------------------------------------------------------------*/
- strcpy(write_fname,cf->fpath);
- strcat(write_fname,cf->fname);
- /*---------------------------------------------------------------------*/
- /* If the file exists, test to make sure we can write it and save a */
- /* backup copy. */
- /*---------------------------------------------------------------------*/
- if (file_exists(write_fname))
- {
- /*---------------------------------------------------------------------*/
- /* Test to make sure that we can write the file. */
- /*---------------------------------------------------------------------*/
- if (!file_writable(write_fname))
- {
- display_error(8,write_fname,FALSE);
- if (bak_filename != (CHARTYPE *)NULL)
- (*the_free)(bak_filename);
- if (write_fname != (CHARTYPE *)NULL)
- (*the_free)(write_fname);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_ACCESS_DENIED);
- }
- /*---------------------------------------------------------------------*/
- /* Rename the current file to filename.bak. */
- /*---------------------------------------------------------------------*/
- if (cf->backup != BACKUP_OFF)
- {
- if ((bak_filename =
- (CHARTYPE *)(*the_malloc)(strlen(cf->fpath)+strlen(cf->fname)+5)) == NULL)
- {
- display_error(30,(CHARTYPE *)"",FALSE);
- if (bak_filename != (CHARTYPE *)NULL)
- (*the_free)(bak_filename);
- if (write_fname != (CHARTYPE *)NULL)
- (*the_free)(write_fname);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OUT_OF_MEMORY);
- }
- new_filename(cf->fpath,cf->fname,bak_filename,(CHARTYPE *)".bak");
- if (cf->fp != NULL)
- {
- remove_file(bak_filename);
- if (rename(write_fname,bak_filename) != 0)
- {
- display_error(8,write_fname,FALSE);
- if (bak_filename != (CHARTYPE *)NULL)
- (*the_free)(bak_filename);
- if (write_fname != (CHARTYPE *)NULL)
- (*the_free)(write_fname);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_ACCESS_DENIED);
- }
- }
- }
- }
- }
- /*---------------------------------------------------------------------*/
- /* Open the file we are writing to... */
- /*---------------------------------------------------------------------*/
- if (append == TRUE)
- fp = fopen(write_fname,"ab");
- else
- fp = fopen(write_fname,"wb");
- if (fp == NULL)
- {
- display_error(8,(CHARTYPE *)"could not open for writing",FALSE);
- if (bak_filename != (CHARTYPE *)NULL)
- (*the_free)(bak_filename);
- if (write_fname != (CHARTYPE *)NULL)
- (*the_free)(write_fname);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_ACCESS_DENIED);
- }
- /*---------------------------------------------------------------------*/
- /* Determine where to start writing from in the linked list. */
- /*---------------------------------------------------------------------*/
- curr = lll_find(cf->first_line,start_line);
- /*---------------------------------------------------------------------*/
- /* Now write out the contents of the file array to the new filename. */
- /*---------------------------------------------------------------------*/
- rc = RC_OK;
- for (j=0L;j<num_lines && curr->next != NULL;j++)
- {
- if (start_line+j != 0L
- && (ignore_scope
- || in_scope(curr)
- || CURRENT_VIEW->scope_all))
- {
- if (cf->tabsout_on)
- {
- col = 0;
- off = start_col;
- while (1)
- {
- newcol = col;
- while ((c = next_char(curr,&off,end_col+1)) == ' ')
- {
- newcol++;
- if ((newcol % cf->tabsout_num) == 0)
- {
- if ((rc = write_char((CHARTYPE)'\t',fp)) == RC_DISK_FULL)
- break;
- col = newcol;
- }
- }
- for (;col<newcol;col++)
- if ((rc = write_char((CHARTYPE)' ',fp)) == RC_DISK_FULL)
- break;
- if (off == (-1)) /* end of line */
- break;
- if ((rc = write_char((CHARTYPE)c,fp)) == RC_DISK_FULL)
- break;
- col++;
- }
- if (rc) break;
- }
- else
- {
- for (i=start_col;i<min(curr->length,end_col+1);i++)
- if ((rc = write_char((CHARTYPE)*(curr->line+i),fp)) == RC_DISK_FULL)
- break;
- }
- if (rc) break;
- /* col = 0;*/
- if (cf->eolout == EOLOUT_CRLF)
- {
- if ((rc = write_char((CHARTYPE)'\r',fp)) == RC_DISK_FULL)
- break;
- }
- if ((rc = write_char((CHARTYPE)'\n',fp)) == RC_DISK_FULL)
- break;
- }
- if (rc)
- break;
- curr = curr->next;
- }
- anerror = errno;
- if (fflush(fp) == EOF)
- {
- rc = RC_DISK_FULL;
- clearerr(fp);
- }
- if (fclose(fp) == EOF)
- rc = RC_DISK_FULL;
- if (rc)
- clearerr(fp);
- /*---------------------------------------------------------------------*/
- /* If an error occurred in writing the file (usuallly a result of a */
- /* disk full error), get the files back to the way they were before */
- /* this attempt to write them. */
- /*---------------------------------------------------------------------*/
- if (rc)
- {
- /* remove 'new' file (the one that couldn't be written) */
- remove_file(write_fname);
- if (same_file)
- {
- if (rename(bak_filename,write_fname) != 0)
- {
- display_error(8,write_fname,FALSE);
- if (bak_filename != (CHARTYPE *)NULL)
- (*the_free)(bak_filename);
- if (write_fname != (CHARTYPE *)NULL)
- (*the_free)(write_fname);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_ACCESS_DENIED);
- }
- }
- }
- else
- {
- if (cf->fmode != 0)
- chmod(write_fname,cf->fmode);
- /*---------------------------------------------------------------------*/
- /* If a backup file is not to be kept, remove the backup file provided */
- /* that there hasn't been a problem in writing the file. */
- /*---------------------------------------------------------------------*/
- if (cf->backup == BACKUP_TEMP)
- remove_file(bak_filename);
- /*---------------------------------------------------------------------*/
- /* If a new filename was not supplied, free up temporary memory. */
- /*---------------------------------------------------------------------*/
- }
- if (bak_filename != (CHARTYPE *)NULL)
- (*the_free)(bak_filename);
- if (write_fname != (CHARTYPE *)NULL)
- (*the_free)(write_fname);
-
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
- /***********************************************************************/
- #ifdef PROTO
- short write_char(CHARTYPE chr,FILE *fp)
- #else
- short write_char(chr,fp)
- CHARTYPE chr;
- FILE *fp;
- #endif
- /***********************************************************************/
- {
- /*--------------------------- local data ------------------------------*/
- /*--------------------------- processing ------------------------------*/
- if (fputc(chr,fp) == chr
- && ferror(fp) == 0)
- return(RC_OK);
- clearerr(fp);
- display_error(57,(CHARTYPE *)"",FALSE);
- return(RC_DISK_FULL);
- }
- /***********************************************************************/
- #ifdef PROTO
- short increment_alt(FILE_DETAILS *cf)
- #else
- short increment_alt(cf)
- FILE_DETAILS *cf;
- #endif
- /***********************************************************************/
- {
- /*--------------------------- local data ------------------------------*/
- CHARTYPE *aus_filename=NULL;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("file.c: increment_alt");
- #endif
- cf->autosave_alt++;
- cf->save_alt++;
- /*---------------------------------------------------------------------*/
- /* We can now test for autosave_alt exceeding the defined limit and */
- /* carry out an autosave if necessary. */
- /*---------------------------------------------------------------------*/
- if (cf->autosave != 0
- && cf->autosave_alt >= cf->autosave)
- {
- if ((aus_filename =
- (CHARTYPE *)(*the_malloc)(strlen(cf->fpath)+strlen(cf->fname)+5)) == NULL)
- {
- display_error(30,(CHARTYPE *)"",FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OUT_OF_MEMORY);
- }
- new_filename(cf->fpath,cf->fname,aus_filename,(CHARTYPE *)".aus");
- save_file(cf,aus_filename,TRUE,cf->number_lines,1L,FALSE,0,max_line_length,TRUE);
- (*the_free)(aus_filename);
- cf->autosave_alt = 0;
- }
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OK);
- }
- /***********************************************************************/
- #ifdef PROTO
- CHARTYPE *new_filename(CHARTYPE *ofp,CHARTYPE *ofn,
- CHARTYPE *nfn,CHARTYPE *ext)
- #else
- CHARTYPE *new_filename(ofp,ofn,nfn,ext)
- CHARTYPE *ofp,*ofn,*nfn,*ext;
- #endif
- /***********************************************************************/
- {
- /*--------------------------- local data ------------------------------*/
- short rc=RC_OK;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("file.c: new_filename");
- #endif
- strcpy(nfn,ofp);
- strcat(nfn,ofn);
- #ifdef DOS
- rc = strzeq(nfn,'.');
- if (rc != (-1))
- *(nfn+rc) = '\0';
- #endif
- #ifdef OS2
- if (!LongFileNames(nfn)) /* returns TRUE if HPFS filesystem */
- {
- rc = strzreveq(nfn,'.');
- if (rc != (-1))
- *(nfn+rc) = '\0';
- }
- #endif
- strcat(nfn,ext);
- #ifdef TRACE
- trace_return();
- #endif
- return(nfn);
- }
- /***********************************************************************/
- #ifdef PROTO
- short remove_aus_file(FILE_DETAILS *cf)
- #else
- short remove_aus_file(cf)
- FILE_DETAILS *cf;
- #endif
- /***********************************************************************/
- {
- /*--------------------------- local data ------------------------------*/
- CHARTYPE *aus_filename=NULL;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("file.c: remove_aus_file");
- #endif
- if ((aus_filename =
- (CHARTYPE *)(*the_malloc)(strlen(cf->fpath)+strlen(cf->fname)+5)) == NULL)
- {
- display_error(30,(CHARTYPE *)"",FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OUT_OF_MEMORY);
- }
- new_filename(cf->fpath,cf->fname,aus_filename,(CHARTYPE *)".aus");
- remove_file(aus_filename);
- (*the_free)(aus_filename);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OK);
- }
- /***********************************************************************/
- #ifdef PROTO
- short free_view_memory(void)
- #else
- short free_view_memory()
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- extern bool curses_started;
- extern CHARTYPE number_of_views;
- extern CHARTYPE display_screens;
- extern CHARTYPE number_of_files;
- /*--------------------------- local data ------------------------------*/
- VIEW_DETAILS *save_current_view=NULL;
- CHARTYPE save_current_screen=0;
- short rc=RC_OK;
- int y=0,x=0;
- int scenario=0;
- ROWTYPE save_cmd_line=0;
- CHARTYPE save_prefix=0;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("file.c: free_view_memory");
- #endif
- /*---------------------------------------------------------------------*/
- /* Before freeing up anything, determine which scenario is current... */
- /*---------------------------------------------------------------------*/
- if (display_screens > 1)
- {
- if (CURRENT_SCREEN.screen_view->file_for_view
- == OTHER_SCREEN.screen_view->file_for_view)
- {
- if (number_of_files > 1)
- scenario = 2;
- else
- scenario = 3;
- }
- else
- scenario = 4;
- }
- else
- {
- if (number_of_files > 1)
- scenario = 1;
- else
- scenario = 0;
- }
- /*---------------------------------------------------------------------*/
- /* Save details of the current view's prefix and cmd_line settings so */
- /* that if the new view has different settings we can adjust the size */
- /* and/or position of the new view's windows. */
- /*---------------------------------------------------------------------*/
- save_prefix = CURRENT_VIEW->prefix;
- save_cmd_line = CURRENT_VIEW->cmd_line;
- /*---------------------------------------------------------------------*/
- /* Free the view... */
- /*---------------------------------------------------------------------*/
- if (--CURRENT_FILE->file_views == 0)
- free_file_memory();
- free_a_view();
-
- switch(scenario)
- {
- case 0:
- /*----------------------------------------------------------*/
- /* +---+---+ */
- /* | a | */
- /* | | --> exit */
- /* |qq | */
- /* +---+---+ */
- /* display_screens = 1 & number_of_files = 1 & same views */
- /* (scenario 0) */
- /*----------------------------------------------------------*/
- break;
- case 1:
- /*----------------------------------------------------------*/
- /* +---+---+ +---+---+ */
- /* | a | b | b | */
- /* | | --> | | */
- /* |qq | | | */
- /* +---+---+ +---+---+ */
- /* display_screens = 1 & number_of_files > 1 & same views */
- /* (scenario 1) */
- /*----------------------------------------------------------*/
- if ((save_prefix&PREFIX_LOCATION_MASK) != (CURRENT_VIEW->prefix&PREFIX_LOCATION_MASK)
- || save_cmd_line != CURRENT_VIEW->cmd_line)
- {
- set_screen_defaults();
- if (curses_started)
- {
- if (set_up_windows(current_screen) != RC_OK)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OK);
- }
- }
- }
- break;
- case 2:
- /*----------------------------------------------------------*/
- /* +---+---+ +---+---+ +---+---+ +---+---+ */
- /* | a | a | b | b | b | or | a | a | b c | b | b | */
- /* | | | --> | | | | | | | | | */
- /* | |qq | | | | | |qq | | | | */
- /* +---+---+ +---+---+ +---+---+ +---+---+ */
- /* display_screens > 1 & number_of_files > 1 & same views */
- /* (scenario 2) */
- /*----------------------------------------------------------*/
- free_file_memory();
- free_a_view();
- save_current_screen = current_screen;
- save_current_view = CURRENT_VIEW;
- current_screen = (current_screen==0)?1:0; /* make other screen current */
- if ((rc = defaults_for_other_files(TRUE)) != RC_OK)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
- CURRENT_FILE = save_current_view->file_for_view;
- CURRENT_FILE->file_views++;
- CURRENT_SCREEN.screen_view = CURRENT_VIEW;
- CURRENT_VIEW = save_current_view;
- current_screen = save_current_screen;
- set_screen_defaults();
- if ((rc = set_up_windows(current_screen)) != RC_OK)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
- pre_process_line(OTHER_SCREEN.screen_view,OTHER_SCREEN.screen_view->focus_line);
- build_other_screen();
- display_other_screen();
- #if 0
- pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
- build_current_screen();
- display_current_screen();
- #endif
- break;
- case 3:
- /*----------------------------------------------------------*/
- /* +---+---+ */
- /* | a | a | */
- /* | | | --> exit */
- /* | |qq | */
- /* +---+---+ */
- /* display_screens > 1 & number_of_files = 1 & same views */
- /* (scenario 3) */
- /*----------------------------------------------------------*/
- CURRENT_FILE->file_views--;
- free_file_memory();
- free_a_view();
- break;
- case 4:
- /*----------------------------------------------------------*/
- /* +---+---+ +---+---+ +---+---+ +---+---+ */
- /* | a | b | | a | a | or | a | b | c | a | a | */
- /* | | | --> | | | | | | | | | */
- /* | |qq | | | | | |qq | | | | */
- /* +---+---+ +---+---+ +---+---+ +---+---+ */
- /* display_screens > 1 & number_of_files > 1 & diff views */
- /* (scenario 4) */
- /*----------------------------------------------------------*/
- if ((rc = defaults_for_other_files(FALSE)) != RC_OK)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
- CURRENT_SCREEN.screen_view = CURRENT_VIEW;
- CURRENT_FILE = OTHER_SCREEN.screen_view->file_for_view;
- CURRENT_FILE->file_views++;
- set_screen_defaults();
- if ((rc = set_up_windows(current_screen)) != RC_OK)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
- /* build_current_screen();
- display_current_screen();*/
- break;
- default:
- break;
- }
-
- if (number_of_views > 0)
- {
- pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
- build_current_screen();
- display_current_screen();
- if (curses_started)
- {
- wmove(CURRENT_WINDOW_MAIN,CURRENT_VIEW->y[WINDOW_MAIN],CURRENT_VIEW->x[WINDOW_MAIN]);
- if (CURRENT_WINDOW_PREFIX != NULL)
- wmove(CURRENT_WINDOW_PREFIX,CURRENT_VIEW->y[WINDOW_PREFIX],CURRENT_VIEW->x[WINDOW_PREFIX]);
- getyx(CURRENT_WINDOW,y,x);
- wmove(CURRENT_WINDOW,y,x);
- }
- }
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OK);
- }
- /***********************************************************************/
- #ifdef PROTO
- void free_a_view(void)
- #else
- void free_a_view()
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- extern CHARTYPE number_of_views;
- extern VIEW_DETAILS *vd_first;
- extern bool curses_started;
- extern VIEW_DETAILS *vd_mark;
- /*--------------------------- local data ------------------------------*/
- register int i;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("file.c: free_a_view");
- #endif
- /*---------------------------------------------------------------------*/
- /* If the marked block is within the current view, unset the variables.*/
- /*---------------------------------------------------------------------*/
- if (MARK_VIEW == CURRENT_VIEW)
- MARK_VIEW = (VIEW_DETAILS *)NULL;
- CURRENT_VIEW = vll_del(&vd_first,NULL,CURRENT_VIEW,DIRECTION_FORWARD);
- CURRENT_SCREEN.screen_view = CURRENT_VIEW;
-
- number_of_views--;
- return;
- }
- /***********************************************************************/
- #ifdef PROTO
- short free_file_memory(void)
- #else
- short free_file_memory()
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- extern CHARTYPE number_of_files;
- /*--------------------------- local data ------------------------------*/
- PPC *curr_ppc=NULL;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("file.c: free_file_memory");
- #endif
- /*---------------------------------------------------------------------*/
- /* If the file name is not NULL, free it... */
- /*---------------------------------------------------------------------*/
- if (CURRENT_FILE->fname != NULL)
- {
- (*the_free)(CURRENT_FILE->fname);
- CURRENT_FILE->fname = (CHARTYPE *)NULL;
- }
- /*---------------------------------------------------------------------*/
- /* If the file path is not NULL, free it... */
- /*---------------------------------------------------------------------*/
- if (CURRENT_FILE->fpath != NULL)
- {
- (*the_free)(CURRENT_FILE->fpath);
- CURRENT_FILE->fpath = (CHARTYPE *)NULL;
- }
- /*---------------------------------------------------------------------*/
- /* Free the linked list of all lines in the file... */
- /*---------------------------------------------------------------------*/
- CURRENT_FILE->first_line = lll_free(CURRENT_FILE->first_line);
- /*---------------------------------------------------------------------*/
- /* Free the linked list of all pending prefix commands... */
- /*---------------------------------------------------------------------*/
- pll_free(CURRENT_FILE->first_ppc);
- /*---------------------------------------------------------------------*/
- /* Free the linked list of reserved lines... */
- /*---------------------------------------------------------------------*/
- rll_free(CURRENT_FILE->first_reserved);
- /*---------------------------------------------------------------------*/
- /* Free the FILE_DETAILS structure... */
- /*---------------------------------------------------------------------*/
- if (CURRENT_FILE != NULL)
- {
- (*the_free)(CURRENT_FILE);
- CURRENT_FILE = (FILE_DETAILS *)NULL;
- }
- number_of_files--;
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OK);
- }
- /***********************************************************************/
- #ifdef PROTO
- short read_directory(void)
- #else
- short read_directory()
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- extern CHARTYPE dir_filename[10];
- extern CHARTYPE dir_path[MAX_FILE_NAME+1];
- extern CHARTYPE *temp_cmd;
- extern CHARTYPE dir_pathname[MAX_FILE_NAME+1];
- extern CHARTYPE sp_path[MAX_FILE_NAME+1];
- extern CHARTYPE sp_fname[MAX_FILE_NAME+1];
- /*--------------------------- local data ------------------------------*/
- struct dirfile *dpfirst=NULL,*dplast=NULL,*dp;
- CHARTYPE str_attr[11];
- CHARTYPE str_date[10];
- CHARTYPE str_time[6];
- #ifdef UNIX
- struct tm *timp;
- #endif
- short rc=RC_OK;
- FILE *fp=NULL;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("file.c: read_directory");
- #endif
- /*---------------------------------------------------------------------*/
- /* Get all file info for the selected files into structure. If no file */
- /* name specified, force it to '*'. */
- /*---------------------------------------------------------------------*/
- if (strcmp(sp_fname,"") == 0)
- rc = getfiles(sp_path,(CHARTYPE *)"*",&dpfirst,&dplast);
- else
- rc = getfiles(sp_path,sp_fname,&dpfirst,&dplast);
- if (rc != RC_OK)
- {
- display_error(rc,sp_path,FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_FILE_NOT_FOUND);
- }
- if (dpfirst == dplast)
- {
- display_error(9,sp_path,FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_FILE_NOT_FOUND);
- }
- /*---------------------------------------------------------------------*/
- /* dir_path is set up here so that subsequent sos_edit commands can use*/
- /* the directory path as a prefix to the edit files filename. */
- /*---------------------------------------------------------------------*/
- strcpy(dir_path,sp_path);
- /*---------------------------------------------------------------------*/
- /* sort the array of file structures. */
- /*---------------------------------------------------------------------*/
- qsort(dpfirst,dplast - dpfirst,sizeof(struct dirfile),fcomp);
- /*---------------------------------------------------------------------*/
- /* open the DIR.DIR file for output, overwriting any previous data */
- /*---------------------------------------------------------------------*/
- strcpy(temp_cmd,dir_pathname);
- strcat(temp_cmd,dir_filename);
- if ((fp = fopen(temp_cmd,"w")) == NULL)
- {
- display_error(8,sp_path,FALSE);
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_ACCESS_DENIED);
- }
- /*---------------------------------------------------------------------*/
- /* write out the formatted contents of the file structures. */
- /*---------------------------------------------------------------------*/
- for (dp=dpfirst;dp<dplast;dp++)
- {
- #ifdef UNIX
- timp = localtime(&(dp->ftime));
- #endif
- fprintf(fp,"%s ",file_attrs(dp->fattr,str_attr));
- fprintf(fp,"%8ld ",dp->fsize);
- fprintf(fp,"%s ",file_date(D_NAME,str_date));
- fprintf(fp,"%s ",file_time(T_NAME,str_time));
- fprintf(fp,"%s\n",dp->fname);
- (*the_free)(dp->fname);
- }
- (*the_free)(dpfirst);
- fclose(fp);
-
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OK);
- }
- /***********************************************************************/
- #ifdef PROTO
- VIEW_DETAILS *find_file(CHARTYPE *fp,CHARTYPE *fn)
- #else
- VIEW_DETAILS *find_file(fp,fn)
- CHARTYPE *fp,*fn;
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- extern VIEW_DETAILS *vd_first;
- /*--------------------------- local data ------------------------------*/
- VIEW_DETAILS *save_current_view=NULL,*found_file=NULL;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("file.c: find_file");
- #endif
- save_current_view = CURRENT_VIEW;
- CURRENT_VIEW = vd_first;
- while(CURRENT_VIEW != (VIEW_DETAILS *)NULL)
- {
- #ifdef UNIX
- if (strcmp(CURRENT_FILE->fname,fn) == 0
- && strcmp(CURRENT_FILE->fpath,fp) == 0)
- #else
- if (stricmp(CURRENT_FILE->fname,fn) == 0
- && stricmp(CURRENT_FILE->fpath,fp) == 0)
- #endif
- {
- #ifdef TRACE
- trace_return();
- #endif
- found_file = CURRENT_VIEW;
- CURRENT_VIEW = save_current_view;
- return(found_file);
- }
- CURRENT_VIEW = CURRENT_VIEW->next;
- }
- #ifdef TRACE
- trace_return();
- #endif
- CURRENT_VIEW = save_current_view;
- return((VIEW_DETAILS *)NULL);
- }
- /***********************************************************************/
- #ifdef PROTO
- short execute_command_file(FILE *fp)
- #else
- short execute_command_file(fp)
- FILE *fp;
- #endif
- /***********************************************************************/
- {
- /*-------------------------- external data ----------------------------*/
- extern CHARTYPE number_of_files;
- /*--------------------------- local data ------------------------------*/
- register short i=0;
- CHARTYPE ch=0;
- short rc=RC_OK;
- CHARTYPE profile_command_line[MAX_LENGTH_OF_LINE];
- short line_number=0;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("file.c: execute_command_file");
- #endif
-
- memset(profile_command_line,' ',MAX_LENGTH_OF_LINE);
- i = 0;
- while(1)
- {
- ch = fgetc(fp);
- if (feof(fp))
- break;
- if (ch == '\n')
- {
- line_number++;
- profile_command_line[i] = '\0';
- rc = process_command_line(profile_command_line,line_number);
- if (rc == RC_SYSTEM_ERROR)
- break;
- if (number_of_files == 0)
- break;
- i = 0;
- memset(profile_command_line,' ',MAX_LENGTH_OF_LINE);
- continue;
- }
- if (ch == '\r')
- {
- profile_command_line[i] = ch;
- i++;
- ch = fgetc(fp);
- if (feof(fp))
- break;
- if (ch == '\n')
- {
- --i;
- line_number++;
- profile_command_line[i] = '\0';
- rc = process_command_line(profile_command_line,line_number);
- if (rc == RC_SYSTEM_ERROR)
- break;
- if (number_of_files == 0)
- break;
- i = 0;
- memset(profile_command_line,' ',MAX_LENGTH_OF_LINE);
- continue;
- }
- }
- profile_command_line[i] = ch;
- i++;
- }
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
- /***********************************************************************/
- #ifdef PROTO
- short process_command_line(CHARTYPE *profile_command_line,short line_number)
- #else
- short process_command_line(profile_command_line,line_number)
- CHARTYPE *profile_command_line;
- short line_number;
- #endif
- /***********************************************************************/
- {
- /*--------------------------- local data ------------------------------*/
- short rc=RC_OK;
- short len=0;
- bool strip=FALSE;
- /*--------------------------- processing ------------------------------*/
- #ifdef TRACE
- trace_function("file.c: process_command_line");
- #endif
- /*---------------------------------------------------------------------*/
- /* If the first line of the macro file does not contains '/*NOREXX' */
- /* abort further processing of the macro file. */
- /*---------------------------------------------------------------------*/
- if (memcmp(profile_command_line,"/*NOREXX*/",10) != 0
- && line_number == 1)
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_SYSTEM_ERROR);
- }
- /*---------------------------------------------------------------------*/
- /* If the line is a comment, return with RC_OK. */
- /*---------------------------------------------------------------------*/
- if (memcmp(profile_command_line,"/*",2) == 0) /* is a comment line */
- {
- #ifdef TRACE
- trace_return();
- #endif
- return(RC_OK);
- }
- /*---------------------------------------------------------------------*/
- /* If the line begins and ends with a quote, single or double, strip */
- /* the quotes. */
- /*---------------------------------------------------------------------*/
- len = strlen(profile_command_line);
- if (*(profile_command_line) == '\''
- && *(profile_command_line+len-1) == '\'')
- strip = TRUE;
- if (*(profile_command_line) == '"'
- && *(profile_command_line+len-1) == '"')
- strip = TRUE;
- if (strip)
- {
- *(profile_command_line+len-1) = '\0';
- profile_command_line++;
- }
- rc = command_line(profile_command_line,COMMAND_ONLY_FALSE);
-
- #ifdef TRACE
- trace_return();
- #endif
- return(rc);
- }
-